package com.xiaoyu.lanling.feature.web.activity

import `in`.srain.cube.util.CLog
import `in`.srain.cube.util.StringUtil
import android.Manifest
import android.annotation.TargetApi
import android.app.Activity
import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.text.TextUtils
import android.webkit.*
import com.tbruyelle.rxpermissions2.RxPermissions
import com.xiaoyu.base.app.GlobalUI
import com.xiaoyu.lanling.R
import com.xiaoyu.lanling.activity.base.AppCompatToolbarActivity
import com.xiaoyu.lanling.common.Constant
import com.xiaoyu.lanling.router.Router
import com.xiaoyu.net.RequestProvider
import kotlinx.android.synthetic.main.activity_web.*
import java.io.File
import java.util.*

class WebActivity : AppCompatToolbarActivity() {

    private lateinit var mWebUrl: String
    private var mUploadMessage: ValueCallback<Uri?>? = null
    private var mFilePathCallback: ValueCallback<Array<Uri>>? = null
    private var mCameraPhotoPath: String? = null

    override fun onCreateSafelyAfterAppFinishInit(savedInstanceState: Bundle?) {
        super.onCreateSafelyAfterAppFinishInit(savedInstanceState)
        setContentView(R.layout.activity_web)
        initToolbar()
        setLightStatusBar()

        mWebUrl = intent.getStringExtra(Constant.PARAM_URL) ?: StringUtil.blank()

        if (TextUtils.isEmpty(mWebUrl)) {
            finish()
            return
        }
        if (!mWebUrl.startsWith("http") && !mWebUrl.startsWith("https")) {
            mWebUrl = "http://$mWebUrl"
        }
        CLog.i(TAG, "web url :$mWebUrl")
        initBaseSupport()
    }


    private fun initBaseSupport() {
        initClient()
        initWebChrome()
        initDownloadListener()
        loadUrl(web_view, mWebUrl)
        addJavascriptInterface()
    }

    private fun addJavascriptInterface() {
        web_view.addJavascriptInterface(JavascriptInterface(this), "CloseWindow")
    }

    private fun initClient() {
        val webViewClient: WebViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView, url: String) {
                super.onPageFinished(view, url)
                addJavascriptInterface()
            }

            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                if (processRequestUri(Uri.parse(url))) {
                    return true
                }
                updateUrl(view, url)
                return true
            }

            @TargetApi(21)
            override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
                if (processRequestUri(request.url)) {
                    return true
                }
                updateUrl(view, request.url.toString())
                return true
            }
        }
        web_view.webViewClient = webViewClient
    }

    private fun initWebChrome() {
        val webChromeClient: WebChromeClient = object : WebChromeClient() {
            override fun onProgressChanged(view: WebView, newProgress: Int) {
                super.onProgressChanged(view, newProgress)
            }

            override fun onReceivedTitle(view: WebView, webTitle: String) {
                if (!TextUtils.isEmpty(webTitle)) {
                    setToolbarTitle(webTitle)
                }
                super.onReceivedTitle(view, webTitle)
            }

            // For Android 4.1+
            fun openFileChooser(uploadMsg: ValueCallback<Uri?>?, acceptType: String?, capture: String?) {
                CLog.i(TAG, "Android 4.1+")
                mUploadMessage?.onReceiveValue(null)
                mUploadMessage = uploadMsg
                permissions()
            }

            // Android 5.0+
            override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: FileChooserParams): Boolean {
                CLog.i(TAG, "Android 5.0+")
                mFilePathCallback?.onReceiveValue(null)
                mFilePathCallback = filePathCallback
                permissions()
                return true
            }
        }
        web_view.webChromeClient = webChromeClient
    }

    private fun initDownloadListener() {
        web_view.setDownloadListener { url, userAgent, contentDisposition, mimeType, _ ->
            val cookies = CookieManager.getInstance().getCookie(url)

            val request = DownloadManager.Request(Uri.parse(url))
            request.setMimeType(mimeType)
            request.addRequestHeader("cookie", cookies)
            request.addRequestHeader("User-Agent", userAgent)
            request.setDescription(getString(R.string.webview_download_file_title))
            request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimeType))
            request.allowScanningByMediaScanner()
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimeType))

            val dm = (getSystemService(DOWNLOAD_SERVICE) as? DownloadManager)
            dm?.enqueue(request)
        }
    }

    private fun processRequestUri(uri: Uri): Boolean {
        if (TextUtils.equals(uri.toString(), Constant.WebAction.CLOSE_ACTIVITY_URL)) {
            finish()
            return true
        }
        return false
    }

    private fun updateUrl(view: WebView, url: String) {
        CLog.i(TAG, "url = $url")
        loadUrl(view, url)
        addJavascriptInterface()
    }

    private fun loadUrl(view: WebView, url: String?) {
        view.loadUrl(url, commonHeader)
    }

    private val commonHeader: Map<String, String>
        get() {
            val stringValueHeader: MutableMap<String, String> = HashMap()
            val objectValueHeader = RequestProvider.getInstance().commonHeaderData
            for ((key, value) in objectValueHeader) {
                if (value != null) {
                    stringValueHeader[key] = value.toString()
                }
            }
            return stringValueHeader
        }

    private fun setToolbarTitle(title: String) {
        setTitle(title + "")
    }

    private fun permissions() {
        if (isFinishing || isDestroyed) {
            return
        }
        RxPermissions(this).request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                .subscribe { granted: Boolean ->
                    if (granted) {
                        startChooseImage()
                    } else {
                        GlobalUI.getInstance().showToast("请在 设置-应用管理 中开启此应用的授权")
                    }
                }
    }

    private fun startChooseImage() {
        var takePictureIntent: Intent? = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        if (takePictureIntent?.resolveActivity(packageManager) != null) {
            val photoFile = createImageFile()
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile))
            mCameraPhotoPath = photoFile.absolutePath
        } else {
            takePictureIntent = null
        }
        val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE)
        contentSelectionIntent.type = "image/*"

        val intentArray = takePictureIntent?.let { arrayOf(it) } ?: emptyArray()
        val chooserIntent = Intent(Intent.ACTION_CHOOSER)
        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "选择图片")
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray)
        startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE)
    }

    private fun createImageFile(): File {
        return File(Environment.getExternalStorageDirectory().toString() + File.separator + System.currentTimeMillis() + ".jpg")
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == INPUT_FILE_REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                if (mUploadMessage == null || mFilePathCallback == null) {
                    super.onActivityResult(requestCode, resultCode, data)
                }
                var result = data?.data
                if (result == null) {
                    try {
                        // 从相机获取
                        val cameraFile = File(mCameraPhotoPath)
                        if (cameraFile.exists()) {
                            result = Uri.fromFile(cameraFile)
                            // 扫描相册
                            sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result))
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
                if (result != null) {
                    CLog.i(TAG, "图片路径=" + result.path)
                    handleInputFileSuccess(arrayOf(result))
                } else {
                    handleInputFileFailed()
                }
            } else {
                handleInputFileFailed()
            }
        }
        super.onActivityResult(requestCode, resultCode, data)
    }

    private fun handleInputFileSuccess(result: Array<Uri>) {
        mUploadMessage?.onReceiveValue(result[0])
        mUploadMessage = null
        mFilePathCallback?.onReceiveValue(result)
        mFilePathCallback = null
    }

    private fun handleInputFileFailed() {
        mUploadMessage?.onReceiveValue(null)
        mUploadMessage = null
        mFilePathCallback?.onReceiveValue(null)
        mFilePathCallback = null
    }

    override fun onResumeSafelyAfterAppFinishInit(isFirstTimeResume: Boolean) {
        web_view.onResume()
        web_view.resumeTimers()
    }

    override fun onPause() {
        web_view.onPause()
        web_view.pauseTimers()
        super.onPause()
    }

    override fun onDestroy() {
        web_view.destroy()
        super.onDestroy()
    }

    inner class JavascriptInterface(private val context: Context) {
        @android.webkit.JavascriptInterface
        fun openImage(img: String) {
            if (img.lastIndexOf("?") < 0) {
                return
            }
            val imageUrl = img.substring(0, img.lastIndexOf("?"))
            val photoList = ArrayList<String>()
            photoList.add(imageUrl)
            Router.instance.gotoPhotoActivity(context, imageUrl, photoList);
        }

        @android.webkit.JavascriptInterface
        fun onCallBack() {
            finish()
        }

    }

    companion object {
        private const val TAG = "WebActivity"
        private const val INPUT_FILE_REQUEST_CODE = 1
    }
}